# In item based widgets, even though two or more widgets have the same data, they store different copies of it.
# This may be good in some cases but if we want synchronization of the same data in all widgets then we must use signals and slots.
# To avoid this, an easier method is to use model view programming. View based widgets utilize a model that holds all the data. The model
# has methods and signals that the view operate on for updating the UI and displaying the correct data. It also allows several views
# to register to the same model, thereby displaying the same thing, even if the data changes through editing. No sync errors occur.
import sys
from PySide import QtGui, QtCore
 

class Window(QtGui.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self.setGeometry(200, 200, 450, 450)
        self.setWindowTitle("QListView VS QListWidget")
        
        # The list of items to be displayed
        self.listitems = ["one", "two", "three", "four", "five", "six"]
        
        # First testing the QListWidget and a QComboBox to show the shortcomings of item based programming
        self.listwidget = QtGui.QListWidget()
        self.listwidget.setWindowTitle("ListWidget (Item based)")
        self.listwidget.setMinimumWidth(300)
        self.listwidget.addItems(self.listitems)
        self.listwidget.show()
        # Combo Box
        self.cmbBox = QtGui.QComboBox()
        self.cmbBox.setWindowTitle("ComboBox (item based)")
        self.cmbBox.setMinimumWidth(300)
        self.cmbBox.addItems(self.listitems)
        self.cmbBox.show()
        # Make the items editable
        count = self.listwidget.count()
        for i in range(count):
            item = self.listwidget.item(i)
            item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
            
        # Working with the View based widgets
        # Create listview item
        self.listview = QtGui.QListView()
        self.listview.setWindowTitle("List View (Model-View based)")
        self.listview.setMinimumWidth(300)
        self.listview.show()
        # Create the interface that the view will use to communicate with the data
        self.model = QtGui.QStringListModel(self.listitems)
        # We have the view and the model. Now to bind them together
        self.listview.setModel(self.model)
        # Note that the listview widget is editable by default
        
        # Now to make the combobox with the same model
        self.cmbBox2 = QtGui.QComboBox()
        self.cmbBox2.setWindowTitle("ComboBox (Model-View based)")
        self.cmbBox2.setMinimumWidth(300)
        self.cmbBox2.setModel(self.model)
        self.cmbBox2.show()
        # We can make another listview with the same model
        self.listview2 = QtGui.QListView()
        self.listview2.setWindowTitle("List View 2 (Model-View based)")
        self.listview2.setMinimumWidth(300)
        self.listview2.show()
        self.listview2.setModel(self.model)
        

if __name__ == "__main__":
    appObject = QtGui.QApplication(sys.argv)
    ex = Window()
    ex.show()
    sys.exit(appObject.exec_())
             
